import {
  createElement, useState, useEffect,
  useRef,
} from 'react'
import { createRoot } from 'react-dom/client'
import {
  Dialog,
  DialogHeader,
  DialogTitle,
  DialogContent,
  DialogFooter,
  DialogDescription,
} from './dialog'
import { VisuallyHidden } from '@radix-ui/react-visually-hidden'
import { Button } from './button'
import { cn } from '@/lib/utils'

type DialogOptions = {
  className?: string
  title?: React.ReactNode | (() => React.ReactNode)
  description?: React.ReactNode | undefined
  onConfirm: () => void | Promise<void>
  onCancel?: () => void | Promise<void>
  content: React.ReactNode | (() => React.ReactNode)
  confirmText?: string
  cancelText?: string | undefined
}

const showDialog = (options: DialogOptions): { close: () => void, update: (newOptions: Partial<DialogOptions>) => void } => {
  const dialogContainer = document.createElement('div')
  document.body.appendChild(dialogContainer)

  let renderCount = 0
  // 更新对话框配置（会触发重新渲染）
  const update = (newOptions: Partial<DialogOptions>) => {
    options = { ...options, ...newOptions }
    renderCount += 1 // 通过改变 key 强制重新渲染
  }

  const DialogComponent = (): JSX.Element => {

    const [open, setOpen] = useState(true)


    const closeDialog = (): void => {
      setOpen(false)
      dialogContainer.remove()
      root.unmount()
    }

    const handleConfirm = async (): Promise<void> => {
      if (options.onConfirm) {
        await options.onConfirm()
      }
      closeDialog()
    }

    const handleCancel = async (): Promise<void>  => {
      if (options.onCancel) {
        await options.onCancel()
      }
      closeDialog()
    }

    const handleOpenChange = (open: boolean): void => {
      if (!open) {
        closeDialog()
      }
    }

    const getTitle = (): React.ReactNode => {
      return typeof options.title === 'function'
        ? options.title()
        : options.title
    }

    const getContent = (): React.ReactNode => {
      return typeof options.content === 'function'
        ? options.content()
        : options.content
    }

    return <Dialog open={open} onOpenChange={handleOpenChange} key={renderCount}>
      <DialogContent className={cn('max-w-sm', options.className)}>
        {options.title ? <DialogHeader>
          <DialogTitle>{getTitle()}</DialogTitle>
          <DialogDescription>{options.description}</DialogDescription>
        </DialogHeader> : <VisuallyHidden><DialogHeader>
          <DialogTitle>{getTitle()}</DialogTitle>
          <DialogDescription>{options.description}</DialogDescription>
        </DialogHeader></VisuallyHidden>}
        <div>
          {getContent()}
        </div>
        <DialogFooter className='flex justify-center items-center gap-2 sm:justify-center'>
          {options.cancelText && <Button variant='outline' onClick={handleCancel}>{options.cancelText}</Button>}
          <Button onClick={handleConfirm}>{options.confirmText ?? 'Confirm'}</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  }

  const root = createRoot(dialogContainer)
  root.render(createElement(DialogComponent))

  return { close, update }
}

const dialog = {
  info: (options: DialogOptions) => {
    return showDialog({
      confirmText: '确定',
      cancelText: undefined,
      ...options,
    })
  },
  confirm: (options: DialogOptions) => {
    return showDialog({
      confirmText: '确定',
      cancelText: '取消',
      ...options,
    })
  }
}

export default dialog